package cc.tuhaolicai.mt.user.mobile.controller.root;

import cc.tuhaolicai.mt.user.mobile.annotation.Mapping;
import cc.tuhaolicai.mt.user.mobile.business.handler.BusinessHandler;
import cc.tuhaolicai.mt.user.mobile.business.model.Node;
import cc.tuhaolicai.mt.user.mobile.business.model.Workflow;
import cc.tuhaolicai.mt.user.mobile.controller.BaseController;
import cc.tuhaolicai.mt.user.mobile.tool.PageInfo;
import cc.tuhaolicai.mt.user.mobile.tool.ToolComparatorList;
import cc.tuhaolicai.mt.user.mobile.tool.ToolMongo;
import com.google.common.collect.Maps;
import org.asyou.mongo.Page;
import pro.tools.data.text.ToolJson;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 业务链controller
 *
 * @author chenli
 * @create 2017-10-12
 */
@Mapping(value = "/service/chain", viewPath = "/admin/chain")
public class ServiceChainController extends BaseController {

    public void index() {
        render("index.jsp");
    }

    public void indexPage() {
        PageInfo pageInfo = new PageInfo();
        pageInfo.setPageIndex(0);
        pageInfo.setPageSize(100000);
        Page<Workflow> page = ToolMongo.findPage(new Workflow(), pageInfo);
        renderJson(page);
    }

    public void checkChain() {
        Long workflowId = getParaToLong(0);
        setAttr("workflowId", workflowId);
        render("workflowPage.jsp");
    }

    public void workflow() {
        Long workflowId = getParaToLong(0);
        Workflow workflow = ToolMongo.findOne(new Workflow().setId(workflowId));
        List<Node> nodeLinkedList = workflow.getNodeLinkedList();
        Map<String, Integer> sort = Maps.newHashMap();
        sort.put("sort", -1);
        nodeLinkedList.sort(new ToolComparatorList<>(sort));
        renderJson(nodeLinkedList);
    }

    public void nodeParams() {
        Long workflowId = getParaToLong(0);
        Integer sort = getParaToInt(1);
        Workflow workflow = ToolMongo.findOne(new Workflow().setId(workflowId));
        List<Node> nodeLinkedList = workflow.getNodeLinkedList();
        Node node = null;
        for (Node oldNode : nodeLinkedList) {
            if (Objects.equals(sort, oldNode.getSort())) {
                node = oldNode;
            }
        }
        render("nodeParams.jsp");
        if (node == null) {
            return;
        }
        setAttr("startParams", node.getStartParams());
        setAttr("stopParams", node.getStopParams());
    }

    public void executeAgain() {
        Long workflowId = getParaToLong(0);
        Workflow workflow = ToolMongo.findOne(new Workflow().setId(workflowId));
        List<Node> nodeLinkedList = workflow.getNodeLinkedList();
        Queue<Node> nodeQueue = new ConcurrentLinkedQueue<>();
        Map<String, Integer> sort = Maps.newHashMap();
        sort.put("sort", -1);
        nodeLinkedList.sort(new ToolComparatorList<>(sort));
        nodeLinkedList.forEach(node -> {
            if (node.getStatus() != 1) {
                nodeQueue.offer(node);
            }
        });
        BusinessHandler start = null;
        Node node = nodeQueue.peek();
        String handlerClassName = node.getHandlerClassName();
        Map<String, Object> params = ToolJson.jsonToMap(node.getStartParams());
        try {
            start = (BusinessHandler) Class.forName(handlerClassName).newInstance();
            start.setName(node.getNodeName());
            start.setSort(node.getSort());
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            nodeQueue.remove(node);
        }
        if (start == null) {
            throw new RuntimeException("错了");
        }
        BusinessHandler nowBusinessHandler = start;

        while (!nodeQueue.isEmpty()) {
            Node nextNode = nodeQueue.peek();
            try {
                BusinessHandler nextBusinessHandler = (BusinessHandler) Class.forName(nextNode.getHandlerClassName()).newInstance();
                nextBusinessHandler.setName(nextNode.getNodeName());
                nowBusinessHandler.setNextHandler(nextBusinessHandler);
                nowBusinessHandler = nextBusinessHandler;
            } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
                e.printStackTrace();
            } finally {
                nodeQueue.remove(nextNode);
            }
        }
        start.start(params, workflow);
        renderJson("成功");
    }

}